/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lcd.h"
#include "string.h"
#include "stdio.h"
#include "key.h"
#include "led.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
//显示参数
#define LCD_Show_Data 0
#define LCD_Show_Para 1
_Bool LCD_show = LCD_Show_Data;
float r37_vlot,Vmax = 3.0f,Vmin = 1.0f;
uint32_t Time;
void LCD_Process(void)
{
	uint8_t LCD_buf[20];
	if(LCD_show == LCD_Show_Data)
	{
		LCD_DisplayStringLine(Line0,(uint8_t*)"      Data");
		
		sprintf((char *)LCD_buf," V:%4.2fV",r37_vlot);
		LCD_DisplayStringLine(Line2,LCD_buf);
		sprintf((char *)LCD_buf," T:%ds   ",Time);
		LCD_DisplayStringLine(Line3,LCD_buf);
	}
	else
	{
		LCD_DisplayStringLine(Line0,(uint8_t*)"      Para");
		
		sprintf((char *)LCD_buf," Vmax:%3.1fV",Vmax);
		LCD_DisplayStringLine(Line2,LCD_buf);
		sprintf((char *)LCD_buf," Vmin:%3.1fV",Vmin);
		LCD_DisplayStringLine(Line3,LCD_buf);
	}
}

//检查设置参数是否有误 错误返回1 
float Vmax_either;
float Vmin_either;
_Bool Check_Para(void)
{
	if((Vmax >= (Vmin + 1)) && Vmax >= 0 && Vmax <= 3.3f && Vmin >= 0 && Vmin <= 3.3f )
	{
		return 0;
	}
	else
		return 1;
}

//按键
uint32_t Key_tick;
_Bool LED_flag_Key;		//LED2控制
void Key_Process(void)
{
	if(uwTick - Key_tick < 20) return ;
	Key_tick = uwTick;
	
	KEY_Read();
	if(Trg & 0x01)
	{
		LCD_show = !LCD_show;
		LCD_Clear(Black);
		if(LCD_show == LCD_Show_Data)
		{
			if(Check_Para())
			{
				LED_flag_Key = 1;
				Vmax = Vmax_either;
				Vmin = Vmin_either;
			}
			else
			{
				LED_flag_Key = 0;
			}
		}
		else
		{
			Vmax_either = Vmax;
			Vmin_either = Vmin;
		}
	}
	if(LCD_show == LCD_Show_Para)
	{
		if(Trg & 0x02)
		{
			Vmax += 0.1f;
			if(Vmax > 3.3f)
			{
				Vmax = 0;
			}
		}
		if(Trg & 0x04)
		{
			Vmin += 0.1f;
			if(Vmin > 3.3f)
			{
				Vmin = 0;
			}
		}
	}
}

//AD
uint16_t ad_value;
void AD_Process(void)
{
	HAL_ADC_Start(&hadc2);
	
	ad_value = HAL_ADC_GetValue(&hadc2);
	r37_vlot = ad_value / 4095.0f * 3.3f;
}

//AD_Check_volt
_Bool AD_Check_flag;
void AD_Check_vlot(void)
{
	if((r37_vlot > Vmin) && (r37_vlot < Vmax))
	{
		AD_Check_flag = 1;
	}
	else
		AD_Check_flag = 0;
}

//检查字符串 错误返回1
_Bool Check_str(uint8_t * str)
{
	if((str[1] == '.') && (str[3] == ',') && (str[5] == '.') && 
	   (str[0] >= '0') && (str[0] <= '9') && (str[2] >= '0') && (str[2] <= '9') &&
	   (str[4] >= '0') && (str[4] <= '9') && (str[6] >= '0') && (str[6] <= '9'))
	{
		return 0;
	}
	else
		return 1;
}

//串口回调
uint32_t Rx_tick;
_Bool LED_flag_uart;
uint8_t uart_buf[2];
uint8_t rx_buf[7];
uint8_t rx_count;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	Rx_tick = uwTick;
	rx_buf[rx_count ++] = uart_buf[0];
	HAL_UART_Receive_IT(&huart1,uart_buf,1);
	
	if(rx_count == 7)
	{
		rx_count = 0;
		if(Check_str(rx_buf))	//判断字符格式
		{
			printf("Error\r\n");
			LED_flag_uart = 1;
		}
		else	//判断
		{
			Vmax_either = Vmax;
			Vmin_either = Vmin;
			Vmax = rx_buf[0] - '0' + 0.1f * (rx_buf[2] - '0');
			Vmin = rx_buf[4] - '0' + 0.1f * (rx_buf[6] - '0');
			if(Check_Para())	//判断定义参数大小是否合规
			{
				printf("Error\r\n");
				LED_flag_uart = 1;
				Vmax = Vmax_either;
				Vmin = Vmin_either;			
			}
			else
			{
				LED_flag_uart = 0;
			}
		}
	}
}

//串口函数
void RX_Process(void)
{
	if(uwTick - Rx_tick < 50) return;
	Rx_tick = uwTick;
	
	if(rx_count > 0)
	{
		printf("Error\r\n");
		LED_flag_uart = 1;
	}

	rx_count = 0;
	memset(rx_buf,'\0',sizeof(rx_buf));
}


//系统中断
uint32_t Time_count;
uint8_t Time_flag;
void SysTick_Handler(void)
{
	HAL_IncTick();
	if((AD_Check_flag == 1) && (LCD_show == 0))
	{
		Time_count++;
		Time_flag = 1;
		if(Time_count == 1001)
		{
			Time ++;
			Time_count = 0;
		}
	}
	else
	{
		Time_count = 0;
		Time = 0;
		Time_flag = 0;
	}
}

//LED
uint8_t LED_con;
void LED_Process(void)
{
	if(Time_flag > 0)
		LED_con |= 0x01;
	else
		LED_con &= ~0x01;
	
	if(LED_flag_Key)
		LED_con |= 0x02;
	else
		LED_con &= ~0x02;
	
	if(LED_flag_uart)
		LED_con |= 0x04;
	else
		LED_con &= ~0x04;
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC2_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	HAL_UART_Receive_IT(&huart1,uart_buf,1);
    LCD_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

    LCD_Clear(Black);
    LCD_SetBackColor(Black);
    LCD_SetTextColor(White);

	LED_ctl(0x00);
	
    while (1)
    {
    /* USER CODE END WHILE */
		LCD_Process();
		Key_Process();
		RX_Process();
		AD_Process();
		AD_Check_vlot();
		LED_Process();
		LED_ctl(LED_con);
    /* USER CODE BEGIN 3 */
    }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
  RCC_OscInitStruct.PLL.PLLN = 20;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the peripherals clocks
  */
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_ADC12;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
  PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
       tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
